<?php
/**
 * Created by PhpStorm.
 * User: shaowei
 * Date: 2018/12/22
 * Time: 下午2:04
 */

namespace App\Http\Model;

use http\Env\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;

class RoomMicro extends Base
{
    private $redis_room_micro_key = "ROOM:MICRO:"; //ROOM:MICRO:{room_id}-{micro_id}
    private $redis_room_micro_user_key = "ROOM:MICROUSER:"; //ROOM:MICROUSER:{room_id}
    private $redis_room_micro_into_begin_key = "ROOM:MICROINTOBEGIN:"; //ROOM:MICROINTOBEGIN:{room_id}-{user_id}

    //房间锁麦缓存
    protected $roomMicroLockRoomKey = 'ROOM:MICROLOCK:ROOM:';//string ROOM:MICROLOCK:{roomId}:{microId} => {string}
    //房间锁麦用户缓存
    protected $roomMicroLockUserKey = 'ROOM:MICROLOCK:USER:';//string ROOM:MICROLOCK:{userId} => {string}

    public function __construct(array $attributes = [])
    {
        parent::__construct($this->table, $attributes);
    }


    /**
     * 清理 redis 数据
     * @param $room_id
     */
    public function remove($room_id){
        $redis_key = $this->redis_room_micro_user_key . $room_id;
        Redis::DEL($redis_key);
        for ($i = 0; $i < 8; $i++){
            $redis_key = $this->redis_room_micro_key . $room_id . '-' . $i;
            Redis::DEL($redis_key);
        }
    }

    /**
     * 设置用户在麦的状态
     * @param $room_id
     * @param $user_id
     * @param $micro_id
     * @param $status 0.上麦中、1.已经上麦
     * @return bool
     */
    public function set_user_micro_status($room_id, $user_id, $micro_id, $status){
        $micro_id = (int) $micro_id;
        $status = (int) $status;
        $redis_key = $this->redis_room_micro_user_key . $room_id;
        Redis::HSET($redis_key, $user_id, ($micro_id.','.$status));

        return true;
    }

    /**
     * 移除用户的上麦状态
     * @param $room_id
     * @param $user_id
     * @return bool
     */
    public function del_user_micro_status($room_id, $user_id){
        $redis_key = $this->redis_room_micro_user_key . $room_id;
        Redis::HDEL($redis_key, $user_id);

        return true;
    }


    /**
     * 获取用户上麦状态
     * @param $room_id
     * @param $user_id
     * @return array|null   ["micro_id":0,"status":0] 0.上麦中、1.已经上麦
     */
    public function get_user_micro_status($room_id, $user_id){
        $redis_key = $this->redis_room_micro_user_key . $room_id;
        $ret = Redis::HGET($redis_key, $user_id);
        if ($ret === null){
            //判断是否锁麦
            $info = $this->getRoomLockMicroByUserId($user_id, $room_id);
            if(!empty($info)) {
                return [
                    'micro_id' => intval($info['micro_id']),
                    'status' => 1
                ];
            }
            return null;
        }
        $arr = explode(',', $ret);
        return [
            'micro_id' => intval($arr[0]),
            'status' => intval($arr[1])
        ];
    }


    /**
     * 获得麦用户ID
     * @param $room_id
     * @param $micro_id
     * @return null|int
     */
    public function get_user_id($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $user_id = Redis::HGET($redis_key, 'user_id');
        if (empty($user_id)){
            //判断是否锁麦
            $info = $this->getRoomLockMicro($room_id, $micro_id);
            if(!empty($info)) {
                return intval($info['lock_user_id']);
            }

            return null;
        }
        return intval($user_id);
    }

    /**
     * 设置麦用户ID
     * @param $room_id
     * @param $micro_id
     * @param $user_id
     * @return bool
     */
    public function set_user_id($room_id, $micro_id, $user_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'user_id', $user_id);
        Redis::HDEL($redis_key, 'volume');
        Redis::HDEL($redis_key, 'volume_self');
        $this->del_gift($room_id, $micro_id);

        return true;
    }

    /**
     * 删除麦用户
     * @param $room_id
     * @param $micro_id
     * @return bool
     */
    public function del_user_id($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HDEL($redis_key, "user_id");
        Redis::HDEL($redis_key, 'volume');
        Redis::HDEL($redis_key, 'volume_self');
        $this->del_gift($room_id, $micro_id);

        return true;
    }

    /**
     * 获取麦克风
     * @param $room_id
     * @param $micro_id
     * @return bool
     */
    public function get_volume($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $volume = Redis::HGET($redis_key, 'volume');
        if ($volume == null){
            return true;
        }
        if (intval($volume) == 1){
            return true;
        }
        return false;
    }

    public function get_volume_self($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $volume_self = Redis::HGET($redis_key, 'volume_self');
        if ($volume_self == null){
            return true;
        }
        if (intval($volume_self) == 1){
            return true;
        }
        return false;
    }

    /**
     * 开麦 主持设置
     */
    public function volume_open($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'volume', 1);
        return true;
    }

    /**
     * 开麦 用户设置
     */
    public function volume_self_open($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'volume_self', 1);
        return true;
    }

    /**
     * 设置麦 关
     * @param $room_id
     * @param $micro_id
     * @return bool
     */
    public function volume_close($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'volume', 0);
        return true;
    }

    public function volume_self_close($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'volume_self', 0);
        return true;
    }

    /**
     * 获得老板位置
     * @param $room_id
     * @param $micro_id
     * @return bool
     */
    public function get_boss($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $boss = Redis::HGET($redis_key, 'boss');
        if ($boss == null){
            return false;
        }
        if (intval($boss) == 1){
            return true;
        }
        return false;
    }

    /**
     * 设置老板位 开
     * @param $room_id
     * @param $micro_id
     * @return bool
     */
    public function boss_open($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'boss', 1);
        return true;
    }

    /**
     * 设置老板位 关
     * @param $room_id
     * @param $micro_id
     * @return bool
     */
    public function boss_close($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'boss', 0);
        return true;
    }

    /**
     * 获取锁状态
     * @param $room_id
     * @param $micro_id
     * @return bool
     */
    public function get_lock($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $lock = Redis::HGET($redis_key, 'lock');
        if ($lock == null){
            return false;
        }
        if (intval($lock) == 0){
            return false;
        }
        return true;
    }

    /**
     * 设置锁状态 unlock
     * @param $room_id
     * @param $micro_id
     * @return bool
     */
    public function lock_open($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'lock', 0);
        return true;
    }

    /**
     * 设置锁状态 lock
     * @param $room_id
     * @param $micro_id
     * @return bool
     */
    public function lock_close($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'lock', 1);
        return true;
    }

    /**
     * 获取性别
     * @param $room_id
     * @param $micro_id
     * @return int 0.普通、1.男、2.女
     */
    public function get_gender($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $gender = Redis::HGET($redis_key, 'gender');
        if ($gender == null){
            return 0;
        }
        return intval($gender);
    }

    /**
     * 设置性别
     * @param $room_id
     * @param $micro_id
     * @param $type 0.普通、1.男、2.女
     */
    public function set_gender($room_id, $micro_id, $type){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'gender', $type);
    }

    /**
     * 获取财富
     * @param $room_id
     * @param $micro_id
     * @return int
     */
    public function get_wealth($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $wealth = Redis::HGET($redis_key, 'wealth');
        if ($wealth == null){
            return 0;
        }
        return intval($wealth);
    }

    /**
     * 重新归零财富
     * @param $room_id
     * @param $micro_id
     * @return bool
     */
    public function reset_wealth($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'wealth', 0);
        return true;
    }

    /**
     * 累加财富值
     * @param $room_id
     * @param $micro_id
     * @param $wealth
     * @return bool
     */
    public function inc_wealth($room_id, $micro_id, $wealth){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HINCRBY($redis_key, 'wealth', $wealth);
        return true;
    }


    /**
     * 获取守护状态
     * @param $room_id
     * @param $micro_id
     * @return int 0.没有守护 1.青铜 2.白银 3.黄金
     */
    public function get_guard($room_id, $micro_id){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $guard = Redis::HGET($redis_key, 'guard');
        if ($guard == null){
            return 0;
        }
        return intval($guard);
    }

    /**
     * 设置守状态
     * @param $room_id
     * @param $micro_id
     * @param $type 0.没有守护 1.青铜 2.白银 3.黄金
     * @return bool
     */
    public function set_guard($room_id, $micro_id, $type){
        $redis_key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HSET($redis_key, 'guard', $type);
        return true;
    }

    /**
     * 获取麦列表
     * @param $room_id
     * @param $room_type 0.普通房间、1.电台房间
     * @return array
     */
    public function get_micros($room_id, $room_type){
        $micro_count = 8;

        $micros = [];
        for ($i = 0; $i < $micro_count; $i++){
            $item = [];
            $item["microphone_id"] = $i;
            $item['user_id'] = $this->get_user_id($room_id, $i);
            $item['volume'] = $this->get_volume($room_id, $i);
            $item['volume_self'] = $this->get_volume_self($room_id, $i);
            $item['boss'] = $this->get_boss($room_id, $i);
            $item['lock'] = $this->get_lock($room_id, $i);
            $item['gender'] = $this->get_gender($room_id, $i);
            $item['wealth'] = $this->get_wealth($room_id, $i);
            $item['guard'] = $this->get_guard($room_id, $i);
            $gift = $this->get_gift($room_id, $i);
            if (!empty($gift)){//重写一下key名,app端保持统一
                $gift['gift_name'] = $gift['name'];
                $gift['gift_image'] = $gift['img'];
                $gift['gift_resource'] = '';
                unset($gift['name']);
                unset($gift['img']);
                unset($gift['price']);
            }

            $item['gift'] = $gift;

            //锁麦
            $item['micro_lock'] = (object) $this->getRoomLockMicro($room_id, $i);
            if(!empty($item['micro_lock']->room_id)) {
                $item['micro_lock']->room_name = '';
            }
            $item['can_lock'] = ($i==0) ? 1 : 0;

            array_push($micros, $item);
        }
        return $micros;
    }


    /**
     * 获取当前在麦用户
     * @param $roomId
     * @return int
     */
    public function getMicroUserCount($roomId){
        $count = 0;
        for ($i = 0; $i < 8; $i++){
            $userId = $this->get_user_id($roomId, $i);
            if (!empty($userId)){
                $count++;
            }
        }
        return $count;
    }


    /**
     * 获取麦信息
     * @param $room_id
     * @param $micro_id
     * @return array|null
     */
    public function get_micro($room_id, $micro_id){
        if (intval($micro_id) >= 8 || intval($micro_id) < 0){
            return null;
        }
        $item = [];
        $item["microphone_id"] = $micro_id;
        $item['user_id'] = $this->get_user_id($room_id, $micro_id);
        $item['volume'] = $this->get_volume($room_id, $micro_id);
        $item['volume_self'] = $this->get_volume_self($room_id, $micro_id);
        $item['boss'] = $this->get_boss($room_id, $micro_id);
        $item['lock'] = $this->get_lock($room_id, $micro_id);
        $item['gender'] = $this->get_gender($room_id, $micro_id);
        $item['wealth'] = $this->get_wealth($room_id, $micro_id);
        $item['guard'] = $this->get_guard($room_id, $micro_id);
        $item['gift'] = $this->get_gift($room_id, $micro_id);
        return $item;
    }

    /**
     * 设置上麦前用户麦关系
     * @param $room_id
     * @param $user_id
     * @param $micro_id
     * @return bool
     */
    public function set_into_begin($room_id, $user_id, $micro_id){
        $key = $this->redis_room_micro_into_begin_key . $room_id . '-' . $user_id;
        Redis::SET($key, $micro_id, 'EX', 10);
        return true;
    }

    /**
     * 删除上麦前用户麦关系
     * @param $room_id
     * @param $user_id
     * @return bool
     */
    public function del_into_begin($room_id, $user_id){
        $key = $this->redis_room_micro_into_begin_key . $room_id . '-' . $user_id;
        Redis::DEL($key);
        return true;
    }

    /**
     * 获取上麦前用户麦
     * @param $room_id
     * @param $user_id
     * @return int|null
     */
    public function get_into_begin($room_id, $user_id){
        $key = $this->redis_room_micro_into_begin_key . $room_id . '-' . $user_id;
        $ret = Redis::GET($key);
        if ($ret === null){
            return null;
        }
        return intval($ret);
    }


    /**
     * 设置麦礼物
     * @param $room_id
     * @param $gift_id
     * @param $gift_name
     * @param $gift_img
     * @param $gift_num
     * @param $gift_price
     */
    public function set_gift($room_id, $user_id, $user_nickname, $user_image, $micro_id, $gift_id, $gift_name, $gift_img, $gift_num, $gift_price){
        $key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $data = [
            'id' => $gift_id,
            'name' => $gift_name,
            'img' => $gift_img,
            'num' => $gift_num,
            'price' => $gift_price,
            'user_id' => $user_id,
            'user_nickname' => $user_nickname,
            'user_image' => $user_image
        ];
        Redis::HSET($key, "gift", json_encode($data));
    }

    /**
     * 删除礼物
     * @param $room_id
     * @return bool
     */
    public function del_gift($room_id, $micro_id){
        $key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HDEL($key, "gift");
        return true;
    }

    /**
     * 获取麦礼物信息
     * @param $room_id
     * @return mixed|null
     */
    public function get_gift($room_id, $micro_id){
        $key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $data = Redis::HGET($key, "gift");
        if (empty($data)){
            return null;
        }
        return json_decode($data, true);
    }

    /**
     * 删除抱麦
     * @param $room_id
     * @return bool
     */
    public function del_hold($room_id, $micro_id){
        $key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        Redis::HDEL($key, "hold");
        return true;
    }

    /**
     * 获取抱麦
     * @param $room_id
     * @return mixed|null
     */
    public function get_hold($room_id, $micro_id){
        $key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $data = Redis::HGET($key, "hold");
        if (empty($data)){
            return null;
        }
        return $data;
    }


    /**
     * 设置抱麦
     * @param $room_id
     * @return mixed|null
     */
    public function set_hold($room_id, $micro_id, $user_id){
        $key = $this->redis_room_micro_key . $room_id . '-' . $micro_id;
        $data = Redis::HSET($key, "hold", $user_id);
    }

    /**设置谁是卧底当前发言人
     * @param $room_id
     * @param $mic_id
     */
    public function setGameSpeakMic($room_id ,$user_id){
        $key = 'GAME:SPEAK:USER:'.$room_id;
        Redis::setex($key , 60 , $user_id);
    }

    /**获取谁是卧底当前发言人
     * @param $room_id
     * @return int
     */
    public function getGameSpeakMic($room_id){
        $key = 'GAME:SPEAK:USER:'.$room_id;
        return Redis::get($key) ?? -2;
    }

    /**删除谁是卧底当前发言人
     * @param $room_id
     */
    public function delGameSpeakMic($room_id){
        $key = 'GAME:SPEAK:USER:'.$room_id;
        Redis::del($key);
    }

    /**
     * 房间锁麦设置
     */
    public function setRoomLockMicro($roomId, $microId, $log){
        //房间麦位=>用户
        $cacheKey = $this->roomMicroLockRoomKey.$roomId.':'.$microId;
        Redis::SET($cacheKey, json_encode($log));
        Redis::EXPIRE($cacheKey, 60*86400);

        //用户=>房间麦位
        $cacheKey = $this->roomMicroLockUserKey.$log['lock_user_id'];
        Redis::SET($cacheKey, json_encode($log));
        Redis::EXPIRE($cacheKey, 60*86400);
    }

    /**
     * 获取房间锁麦设置
     */
    public function getRoomLockMicro($roomId, $microId){
        $result = [];
        do {
            //房间麦位=>用户
            $cacheKey = $this->roomMicroLockRoomKey.$roomId.':'.$microId;
            $log = Redis::GET($cacheKey);
            if(empty($log)) {
                break;
            }
            $log = json_decode($log, true);
            //用户=>房间麦位
            $cacheKey = $this->roomMicroLockUserKey.$log['lock_user_id'];
            $log = Redis::GET($cacheKey);
            //自动解锁
            if(empty($log)) {
                $this->delRoomLockMicro($roomId, $microId);
                break;
            }
            $result = json_decode($log, true);

        } while (false);

        return $result;
    }

    /**
     * 获取用户锁麦设置
     */
    public function getRoomLockMicroByUserId($userId, $roomId=0){
        $result = [];
        do {
            //用户=>房间麦位
            $cacheKey = $this->roomMicroLockUserKey.$userId;
            $log = Redis::GET($cacheKey);
            if(empty($log)) {
                break;
            }
            $log = json_decode($log, true);
            //房间麦位=>用户
            $cacheKey = $this->roomMicroLockRoomKey.$log['room_id'].':'.$log['micro_id'];
            $log = Redis::GET($cacheKey);
            //自动解锁
            if(empty($log)) {
                $this->delRoomLockMicro($log['room_id'], $log['micro_id']);
                break;
            }
            $log = json_decode($log, true);
            if(!empty($roomId) && $roomId!=$log['room_id']) {
                break;
            }
            $result = $log;

        } while (false);

        return $result;
    }

    /**
     * 删除房间锁麦设置
     */
    public function delRoomLockMicro($roomId, $microId){
        do {
            //房间麦位=>用户
            $cacheKey = $this->roomMicroLockRoomKey.$roomId.':'.$microId;
            $log = Redis::GET($cacheKey);
            Redis::DEL($cacheKey);
            if(!empty($log)) {
                $log = json_decode($log, true);
                //用户=>房间麦位
                $cacheKey = $this->roomMicroLockUserKey.$log['lock_user_id'];
                Redis::DEL($cacheKey);
            }
        } while (false);
    }

    /**
     * 清理房间锁麦信息
     */
    public function removeRoomLockMicro($roomId){
        for ($i = 0; $i < 8; $i++){
            $this->delRoomLockMicro($roomId, $i);
        }
    }

    /**
     * 普通麦下麦
     */
    public function roomMicro($roomId){
        for ($i = 0; $i < 8; $i++){
            $this->delRoomLockMicro($roomId, $i);
        }
    }

    /**
     * 获取房间普通麦列表
     */
    public function getRoomMicroList($roomId){
        $list = [];
        for ($i = 0; $i < 8; $i++){
            $userId = $this->get_user_id($roomId, $i);
            if(!empty($userId)) {
                $list[$i] = $userId;
            }
        }

        return $list;
    }





}
